pub mod server_file;
pub mod windows;

use crate::server_file::tauri_file_server;
use crate::windows::{ChatWindowId, ShowChatWindow};
use tauri::Manager;
use tauri_specta::Event;
use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize, Clone, specta::Type)]
pub struct AppInfo {
    name: String,
    path: String,
    icon_path: Option<String>,
}

// demo command
#[tauri::command]
#[specta::specta]
fn greet(app: tauri::AppHandle, name: &str) -> String {
    DemoEvent("Demo event fired from Rust 🦀".to_string())
        .emit(&app)
        .ok();
    format!("Hello, {}! You've been greeted from Rust!", name)
}

// Show launcher command
#[tauri::command]
#[specta::specta]
fn show_launcher(app: tauri::AppHandle) -> Result<(), String> {
    ShowChatWindow::Launcher.show(&app).map_err(|e| e.to_string())?;
    Ok(())
}

// Get installed applications
#[tauri::command]
#[specta::specta]
fn get_installed_apps() -> Result<Vec<AppInfo>, String> {
    #[cfg(target_os = "macos")]
    {
        let apps = applications::Applications::new();
        let installed_apps = apps.get_installed_apps().map_err(|e| e.to_string())?;
        
        let app_info_list = installed_apps
            .iter()
            .map(|app| AppInfo {
                name: app.name.clone(),
                path: app.path.clone(),
                icon_path: app.icon_path.clone(),
            })
            .collect();
        
        Ok(app_info_list)
    }
    
    #[cfg(target_os = "windows")]
    {
        let apps = applications::Applications::new();
        let installed_apps = apps.get_installed_apps().map_err(|e| e.to_string())?;
        
        let app_info_list = installed_apps
            .iter()
            .map(|app| AppInfo {
                name: app.name.clone(),
                path: app.path.clone(),
                icon_path: app.icon_path.clone(),
            })
            .collect();
        
        Ok(app_info_list)
    }
    
    #[cfg(not(any(target_os = "macos", target_os = "windows")))]
    {
        // For Linux or other platforms, return an empty list for now
        Ok(Vec::new())
    }
}

// Process AI query command
#[tauri::command]
#[specta::specta]
async fn process_ai_query(query: String) -> Result<Vec<String>, String> {
    // In a real implementation, you would call an AI service here
    // For now, we'll just return some mock results
    
    // Simulate processing delay
    std::thread::sleep(std::time::Duration::from_millis(300));
    
    let query = query.to_lowercase();
    
    // Return different results based on the query
    let results = if query.contains("settings") {
        vec![
            "Open Settings".to_string(),
            "Change Theme Settings".to_string(),
            "Configure Keyboard Shortcuts".to_string(),
        ]
    } else if query.contains("search") || query.contains("find") {
        vec![
            format!("Search the web for {}", query),
            format!("Search files for {}", query),
            format!("Search emails for {}", query),
        ]
    } else if query.contains("create") || query.contains("new") {
        vec![
            "Create new document".to_string(),
            "Create new spreadsheet".to_string(),
            "Create new presentation".to_string(),
        ]
    } else if query.contains("calculate") || query.starts_with("what is ") {
        vec![
            format!("Calculate {}", query),
            "Open Calculator".to_string(),
            "Convert units".to_string(),
        ]
    } else {
        vec![
            format!("Search the web for {}", query),
            "Open application".to_string(),
            "Create new document".to_string(),
            format!("Translate {}", query),
            "Set a reminder".to_string(),
        ]
    };
    
    Ok(results)
}

// demo event
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, specta::Type, Event)]
pub struct DemoEvent(String);

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    #[cfg(debug_assertions)]
    {
        log::info!("App started!");
        log::warn!("Example Rust Log: warning!");
        log::error!("Example Rust Log: error!");
    }

    let builder = tauri::Builder::default();

    let specta_builder = tauri_specta::Builder::<tauri::Wry>::new()
        .commands(tauri_specta::collect_commands![
            greet, 
            show_launcher, 
            process_ai_query,
            get_installed_apps
        ])
        .events(tauri_specta::collect_events![crate::DemoEvent]);

    #[cfg(all(debug_assertions, not(mobile)))]
    specta_builder
        .export(
            specta_typescript::Typescript::default()
                .formatter(specta_typescript::formatter::prettier),
            "../src/bindings.ts",
        )
        .expect("failed to export typescript bindings");

    builder
        .plugin(tauri_plugin_shell::init())
        .plugin(tauri_plugin_user_input::init())
        .plugin(tauri_plugin_dialog::init())
        .plugin(tauri_plugin_global_shortcut::init())
        .invoke_handler(specta_builder.invoke_handler())
        .setup(move |app| {
            specta_builder.mount_events(app);

            // Register global shortcut to show launcher
            #[cfg(not(mobile))]
            {
                let app_handle = app.handle().clone();
                app.global_shortcut_manager()
                    .register("Alt+Space", move || {
                        let _ = ShowChatWindow::Launcher.show(&app_handle);
                    })
                    .expect("Failed to register global shortcut");
            }

            // listen to demo event
            DemoEvent::listen(app, |event| {
                log::info!("DemoEvent received in Rust:: {:?}", event.payload);
            });

            // dispatch demo event
            DemoEvent("Hello from Rust 🦀".to_string()).emit(app).ok();
            // /dispatch demo event

            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
